package org.jimmy.tang.ssl;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.UnknownHostException;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;

import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.TrustManagerFactory;

/**
 * @author jimmy
 * 
 */
public class SSLClient {
    private static final String DEFAULT_HOST = "10.140.29.48";
    private static final int DEFAULT_PORT = 443;
    private String keyStore = "/home/jimmy/temo/cert/keystore.jks",
            keyPwd = "cisco123";
    private String trustStore = "/home/jimmy/temo/cert/truststore.jks",
            trustPwd = "cisco123";

    private SSLSocket sslSocket;

    /**
     * @param args
     */
    public static void main(String[] args) {

        SSLClient client = new SSLClient();

        client.init();
        client.process();
    }

    private void usage() {

        System.out
                .println("Usage: SSLClient --host host --port port --cert cert_file --cert_pwd pwd --key key_file --key_pwd pwd\n");
    }

    private void process() {

        if (sslSocket == null) {
            System.out.println("ERROR");
            return;
        }
        try {
            sslSocket.startHandshake();

            PrintWriter out = new PrintWriter(new BufferedWriter(
                    new OutputStreamWriter(sslSocket.getOutputStream())));
            out.println("GET /index.html HTTP/1.0");
            out.println();
            out.flush();

            if (out.checkError()) {
                System.out.println("SSLClient:  java.io.PrintWriter error");
            }

            BufferedReader in = new BufferedReader(new InputStreamReader(
                    sslSocket.getInputStream()));
            String inputLine;
            while ((inputLine = in.readLine()) != null) {
                System.out.println(inputLine);
            }

            in.close();
            out.close();

            sslSocket.close();
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println(e);
        }
    }

    private void init() {

        try {
            SSLContext ctx = SSLContext.getInstance("SSL");
            KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
            TrustManagerFactory tmf = TrustManagerFactory
                    .getInstance("SunX509");
            KeyStore ks = null, tks = null;
            try {
                ks = KeyStore.getInstance("JKS");
            } catch (KeyStoreException e) {
                e.printStackTrace();
            }
            try {
                tks = KeyStore.getInstance("JKS");
            } catch (KeyStoreException e) {
                e.printStackTrace();
            }

            try {
                ks.load(new FileInputStream(keyStore), keyPwd.toCharArray());
            } catch (CertificateException e) {
                e.printStackTrace();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }

            try {
                tks.load(new FileInputStream(trustStore),
                        trustPwd.toCharArray());
            } catch (CertificateException e) {
                e.printStackTrace();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }

            try {
                kmf.init(ks, keyPwd.toCharArray());
            } catch (UnrecoverableKeyException e) {
                e.printStackTrace();
            } catch (KeyStoreException e) {
                e.printStackTrace();
            }
            try {
                tmf.init(tks);
            } catch (KeyStoreException e) {
                e.printStackTrace();
            }
            try {
                ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
            } catch (KeyManagementException e) {
                e.printStackTrace();
            }

            try {
                sslSocket = (SSLSocket) ctx.getSocketFactory().createSocket(
                        DEFAULT_HOST, DEFAULT_PORT);
            } catch (UnknownHostException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
                System.out.println("here");
            }
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
    }
}
